/*----------------------------------------------------------------------------
* Copyright (c) KylinIdeTeam. 2022-2023. All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 创建工具条，工具条具有显示隐藏功能，在工具条上创建快捷按钮并能响应动作。
* --------------------------------------------------------------------------- */

import 'vs/css!./media/toolbarpart';
import { localize } from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { Part } from 'vs/workbench/browser/part';
import { MENUBAR_SELECTION_BACKGROUND, MENUBAR_SELECTION_BORDER, TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_BORDER, WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
import { URI } from 'vs/base/common/uri';
import { registerColor, transparent } from 'vs/platform/theme/common/colorRegistry';
import { Color } from 'vs/base/common/color';
import { addDisposableListener, EventHelper, EventType, $ } from 'vs/base/browser/dom';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { FileAccess } from 'vs/base/common/network';
import { IToolBarService } from 'vs/workbench/services/toolbar/common/toolBarService';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction, toAction } from 'vs/base/common/actions';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { dispose } from 'vs/base/common/lifecycle';
import { ToggleToolBarVisibilityAction } from 'vs/workbench/browser/actions/layoutActions';
import { Codicon, CSSIcon } from 'vs/base/common/codicons';
import { isWeb } from 'vs/base/common/platform';
// import { isMacintosh } from 'vs/base/common/platform';
// import { OpenFileFolderAction, OpenFolderAction } from 'vs/workbench/browser/actions/workspaceActions';

export class ToolbarPart extends Part implements IToolBarService {
	declare readonly _serviceBrand: undefined;

	readonly minimumWidth: number = 0;
	readonly maximumWidth: number = Number.POSITIVE_INFINITY;
	readonly minimumHeight: number = 34;
	readonly maximumHeight: number = 34;

	constructor(
		@IStorageService storageService: IStorageService,
		@IThemeService themeService: IThemeService,
		@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
		@IInstantiationService protected readonly instantiationService: IInstantiationService,
		@ICommandService private readonly commandService: ICommandService,
		@IContextMenuService private contextMenuService: IContextMenuService,
	) {
		super(Parts.TOOLBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
	}

	override createContentArea(parent: HTMLElement): HTMLElement {
		this.element = parent;
		const content = document.createElement('div');
		content.classList.add('toolbar-title');
		this.element.appendChild(content);

		const toolitem = [
			// 新建文本文件
			{
				url: FileAccess.asFileUri('./media/newfile.svg', require),
				command: 'workbench.action.files.newUntitledFile',
				arg: '',
				title: localize('newFile', 'New Text File') + '(Ctrl+N)',
				icon: Codicon.newFile
			},
			// 新建窗口
			{
				url: FileAccess.asFileUri('./media/newWindow.svg', require),
				command: 'workbench.action.newWindow',
				arg: '',
				title: localize('newWindow', 'New Window') + '(Ctrl+Shift+N)',
				icon: Codicon.emptyWindow
			},
			// //打开文件夹,有问题
			// {
			// 	url: FileAccess.asFileUri('./media/create.svg', require),
			// 	command: isMacintosh ? 'workbench.action.files.openFileFolder' : 'workbench.action.files.openFolder',
			// 	arg: '',
			// 	title: localize('openFolder', 'Open Folder') + '(Ctrl+K Ctrl+O)',
			// 	icon: Codicon.folderOpened
			// },
			// 撤销
			{
				url: FileAccess.asFileUri('./media/cancel.svg', require),
				command: 'undo',
				arg: '',
				title: localize('undo', 'Undo') + '(Ctrl+Z)',
				icon: Codicon.discard
			},
			//恢复
			{
				url: FileAccess.asFileUri('./media/redo.svg', require),
				command: 'redo',
				arg: '',
				title: localize('redo', 'Redo') + '(Ctrl+Y)',
				icon: Codicon.redo
			},
			// 返回
			{
				url: FileAccess.asFileUri('./media/back.svg', require),
				command: 'workbench.action.navigateBack',
				arg: '',
				title: localize('navigatePrevious', 'Go Back') + '(Ctrl+Alt+-)',
				icon: Codicon.arrowLeft//Codicon.chevronLeft
			},
			//前进
			{
				url: FileAccess.asFileUri('./media/goahead.svg', require),
				command: 'workbench.action.navigateForward',
				arg: '',
				title: localize('navigateNext', 'Go Forward') + '(Ctrl+Shift+-)',
				icon: Codicon.arrowRight//Codicon.chevronRight
			},
			// 向上移动一行
			{
				url: FileAccess.asFileUri('./media/moveLinesUp.svg', require),
				command: 'editor.action.moveLinesUpAction',
				arg: '',
				title: localize('moveLinesUp', 'moveLinesUp') + '(Alt+RightArrow)',
				icon: Codicon.arrowUp
			},
			// 向下移动一行
			{
				url: FileAccess.asFileUri('./media/moveLinesDown.svg', require),
				command: 'editor.action.moveLinesDownAction',
				arg: '',
				title: localize('moveLinesDown', 'moveLinesDown') + '(Alt+LeftArrow)',
				icon: Codicon.arrowDown
			},
			//打开explorer
			{
				url: FileAccess.asFileUri('./media/explorer.svg', require),
				command: 'workbench.view.explorer',
				arg: '',
				title: localize('explorer', 'explorer') + '(Ctrl+Shift+E)',
				icon: Codicon.files
			},
			//开启搜索
			{
				url: FileAccess.asFileUri('./media/search.svg', require),
				command: 'workbench.view.search',
				arg: '',
				title: localize('Search', 'Search') + '(Ctrl+Shift+F)',
				icon: Codicon.search
			},
			//打开源代码管理
			{
				url: FileAccess.asFileUri('./media/scm.svg', require),
				command: 'workbench.view.scm',
				arg: '',
				title: localize('Scm', 'Source Control') + '(Ctrl+Shift+G G)',
				icon: Codicon.sourceControl
			},
			//打开debug
			{
				url: FileAccess.asFileUri('./media/debug.svg', require),
				command: 'workbench.view.debug',
				arg: '',
				title: localize('Run and Debug', 'Run and Debug') + '(Ctrl+Shift+D)',
				icon: Codicon.debugAlt
			},
			//开启插件
			{
				url: FileAccess.asFileUri('./media/extensions.svg', require),
				command: 'workbench.view.extensions',
				arg: '',
				title: localize('Extensions', 'Extensions') + '(Ctrl+Shift+X)',
				icon: Codicon.extensions
			},
			//开启关闭终端
			{
				url: FileAccess.asFileUri('./media/command.svg', require),
				command: 'workbench.action.terminal.toggleTerminal',
				arg: '',
				title: localize('Terminal', 'Terminal') + '(Ctrl+`)',
				icon: Codicon.terminal
			},
			//打开键盘快捷方式
			{
				url: FileAccess.asFileUri('./media/keyboardShortcuts.svg', require),
				command: 'workbench.action.openGlobalKeybindings',
				arg: '',
				title: localize('KeyboardShortcuts', 'Keyboard Shortcuts') + '(Ctrl+K Ctrl+S)',
				icon: Codicon.keyboard
			},
			//打开设置
			{
				url: FileAccess.asFileUri('./media/config-dark.svg', require),
				command: 'workbench.action.openSettings',
				arg: '',
				title: localize('Settings', 'Settings') + '(Ctrl+,)',
				icon: Codicon.gear
			},
			//图片问题svg不显示，注释
			// {
			// 	url: FileAccess.asFileUri('./media/siderbar.svg', require),
			// 	command: 'workbench.action.toggleSidebarVisibility',
			// 	arg: '',
			// 	title: localize('Siderbar', 'Siderbar') + '(Ctrl+B)',
			// 	icon: undefined
			// },
			// {
			// 	url: FileAccess.asFileUri('./media/panel.svg', require),
			// 	command: 'workbench.action.togglePanel',
			// 	arg: '',
			// 	title: localize('Panel', 'Panel') + '(Ctrl+J)',
			// 	icon: undefined
			// },
			//放大窗体
			{
				url: FileAccess.asFileUri('./media/zoomIn.svg', require),
				command: 'workbench.action.zoomIn',
				arg: '',
				title: localize('ZoomIn', 'ZoomIn') + '(Ctrl+=)',
				icon: Codicon.zoomIn
			},
			//缩小窗体
			{
				url: FileAccess.asFileUri('./media/zoomOut.svg', require),
				command: 'workbench.action.zoomOut',
				arg: '',
				title: localize('ZoomOut', 'ZoomOut') + '(Ctrl+-)',
				icon: Codicon.zoomOut
			},
			//全屏模式
			{
				url: FileAccess.asFileUri('./media/screenFull.svg', require),
				command: 'workbench.action.toggleFullScreen',
				arg: '',
				title: localize('FullScreen', 'FullScreen') + '(F11)',
				icon: Codicon.screenFull
			},
			//禅模式
			{
				url: FileAccess.asFileUri('./media/zenMode.svg', require),
				command: 'workbench.action.toggleZenMode',
				arg: '',
				title: localize('ZenMode', 'ZenMode') + '(Ctrl+K Z)',
				icon: Codicon.target
			}
		];

		//添加分隔竖线
		toolitem.forEach(item => {
			if (item.command === 'undo' || item.command === 'workbench.view.explorer' || item.command === 'workbench.action.zoomIn') {
				const toolitem = document.createElement('div');
				toolitem.style.margin = '0 5px 0 5px';
				toolitem.style.height = '23px';
				toolitem.style.border = '0.5px solid';
				toolitem.style.borderColor = '#5C5C5C';
				content.appendChild(toolitem);
			}
			if (isWeb && (item.command === 'workbench.action.zoomIn' || item.command === 'workbench.action.zoomOut')) {
				return;
			}
			this.createToolitem(content, item.url, item.command, item.arg, item.title, item.icon);
		});
		this.updateStyles();

		// Context menu support 鼠标右键菜单
		this._register(addDisposableListener(parent, EventType.CONTEXT_MENU, e => this.showContextMenu(e)));
		return this.element;
	}

	private createToolitem(parent: HTMLElement, url: URI, cmd: string, arg: string, title: string, icon?: Codicon | undefined): void {
		const toolitem = document.createElement('div');
		toolitem.classList.add('tool-item');

		const toolitemicon = document.createElement('div');
		toolitemicon.classList.add('tool-item-icon');

		//没有使用url的图片地址，使用IDE中的默认icon
		if (icon === undefined) {
			const img = document.createElement('img');
			img.title = title;
			img.classList.add('tool-item-icon');
			img.src = url.toString(true);
			toolitemicon.appendChild(img);
		} else {
			const node = $(`span`);
			node.title = title;
			node.classList.add(...CSSIcon.asClassNameArray(icon));
			toolitemicon.appendChild(node);
		}


		toolitem.appendChild(toolitemicon);
		parent.appendChild(toolitem);
		if (cmd.length > 0) {
			this._register(addDisposableListener(toolitem, EventType.MOUSE_DOWN, _e => {
				if (arg.length > 0) {
					this.commandService.executeCommand(cmd, arg);
				}
				else {
					this.commandService.executeCommand(cmd);
				}
			}));
		}
	}

	//显示右键菜单内容
	private showContextMenu(e: MouseEvent): void {
		EventHelper.stop(e, true);

		const event = new StandardMouseEvent(e);

		let actions: IAction[] | undefined = undefined;
		this.contextMenuService.showContextMenu({
			getAnchor: () => ({ x: event.posx, y: event.posy }),
			getActions: () => {
				actions = this.getContextMenuActions(event);

				return actions;
			},
			onHide: () => {
				if (actions) {
					dispose(actions);
				}
			}
		});
	}

	//add context action 填充鼠标右键菜单的事件
	private getContextMenuActions(_event: StandardMouseEvent): IAction[] {
		const actions: IAction[] = [];

		// Toggle Tool Bar
		actions.push(toAction({ id: ToggleToolBarVisibilityAction.ID, label: localize('hideToolBar', 'Hide Tool Bar'), run: async () => this.instantiationService.invokeFunction(accessor => new ToggleToolBarVisibilityAction().run(accessor)) }));

		// 此处可添加右键菜单
		return actions;
	}

	override updateStyles() {
		super.updateStyles();
		// Part container
		if (this.element) {
			const TOOL_BAR_BACKGROUND = registerColor('toolBar.background', {
				dark: transparent(TITLE_BAR_ACTIVE_BACKGROUND, 0.7),
				light: transparent(TITLE_BAR_ACTIVE_BACKGROUND, 0.8),
				hcDark: Color.black, hcLight: Color.white
			}, localize('toolBarBackground', 'Tool bar background'));
			const toolbarBackground = this.getColor(TOOL_BAR_BACKGROUND, (color, theme) => {
				return color.isOpaque() ? color : color.makeOpaque(WORKBENCH_BACKGROUND(theme));
			}) || '';
			this.element.style.backgroundColor = toolbarBackground;
			if (toolbarBackground && Color.fromHex(toolbarBackground).isLighter()) {
				this.element.classList.add('light');
			} else {
				this.element.classList.remove('light');
			}
			const toolbarBorder = this.getColor(TITLE_BAR_BORDER);
			this.element.style.borderBottom = toolbarBorder ? `1px solid ${toolbarBorder}` : '';
		}
	}

	override layout(width: number, height: number): void {
		super.layoutContents(width, height);
	}

	toJSON(): object {
		return {
			type: Parts.TOOLBAR_PART
		};
	}
}

registerThemingParticipant((theme, collector) => {
	const toolBarHoverBg = theme.getColor(MENUBAR_SELECTION_BACKGROUND);
	if (toolBarHoverBg) {
		collector.addRule(`
	.tool-item-icon:hover {
		background: ${toolBarHoverBg};
		border: 0px solid;
	}
	`);
	}
	const toolBarActiveBg = theme.getColor(TITLE_BAR_ACTIVE_BACKGROUND);
	if (toolBarActiveBg) {
		collector.addRule(`
	.tool-item-icon:active {
		background: ${toolBarActiveBg};
		}
	`);
	}
	const toolBarHoverBd = theme.getColor(MENUBAR_SELECTION_BORDER);
	if (toolBarHoverBd) {
		collector.addRule(`
	.tool-item-icon:hover {
		border-color: ${toolBarHoverBd};
		}
	`);
	}
});

registerSingleton(IToolBarService, ToolbarPart);
